﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Input;

namespace InkRun
{
    public class Player : GameObject
    {

        public static Texture2D PlayerSprite1 { get; set; }
        public static Texture2D PlayerSprite2 { get; set; }
        public static Texture2D SplodgeSprite { get; set; }
        public float speedDampener;
        public List<GameObject> splodges;
        public float scale;
        public bool touchingOtherPlayer;
        public ScrollingLevel tileCurrentlyOn;
        public enum PlayerState
        {
            Spawning,
            Alive,
            Dying,
            Dead,
            GameOver
        }

        /// <summary>
        /// The unique ID of the player
        /// </summary>
        public int PlayerID { get; set; }

        public PlayerState  playerState;

        public Vector2 velocity;



        public float timeTillNextShot;

        public int upKey, downKey, leftKey, rightKey, fireKey,debugKeyReInk;
        public Color color;


        public int Lives { get; set; }
        public bool NoLivesLeft { get; set; }

        public Player(Vector2 position) : base(position)
        {
            playerState = PlayerState.Alive;

        }

        public Player(int playerID, Vector2 Position)  : base(Position)
        {
            this.PlayerID = playerID;
            playerState = PlayerState.Alive;
            scale = 0.25f;
            touchingOtherPlayer = false;
            sizeInPixels = new Vector2(scale * Player.PlayerSprite1.Bounds.Width,scale * Player.PlayerSprite1.Bounds.Height);
            this.velocity = new Vector2(0.0f, 0.0f);
            this.timeTillNextShot = GameParameters.PLAYER_FIRE_INTERVAL;
            SetUpPlayer();
            speedDampener = 1.0f;
            // Lives
            splodges = new List<GameObject>();

            Lives = 3;
            NoLivesLeft = false;
        }

        public void SetUpPlayer()
        {
            if (PlayerID == 1)
            {
                upKey = (int)Keys.W;
                downKey = (int)Keys.S;
                leftKey = (int)Keys.A;
                rightKey = (int)Keys.D;
                fireKey = (int)Keys.Space;
                debugKeyReInk = (int)Keys.Escape;
                color = Color.IndianRed; // redish
                
            }
            else if (PlayerID == 2)
            {
                upKey = (int)Keys.Up;
                downKey = (int)Keys.Down;
                leftKey = (int)Keys.Left;
                rightKey = (int)Keys.Right;
                fireKey = (int)Keys.RightShift;
                debugKeyReInk = (int)Keys.F1;
                color = Color.Blue; // purple
            }
        }

        public void ResetPlayer()
        {

        }

        public override void Update(GameTime gameTime)
        {

            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
            timeTillNextShot -= elapsedTime;

            switch (playerState)
            {
                case PlayerState.Spawning:

                    switch (PlayerID)
                    {
                        case 1:
                            Position = GameParameters.PLAYER1_START_POSITION;
                            break;
                        case 2:
                            Position = GameParameters.PLAYER2_START_POSITION;
                            break;
                        default:
                            break;
                          
                    }                   

                    break;
                case PlayerState.Alive:

                    #region Firing

                    if (InputHandler.IsKeyDown((Keys)fireKey) && this.timeTillNextShot < 0)
                    {
                        Splodge();
                        timeTillNextShot = GameParameters.PLAYER_FIRE_INTERVAL;
                    }

                    #endregion Firing

                    #region Movement

                    if (InputHandler.IsKeyDown((Keys)upKey))
                    {
                        if (this.position.Y > (PlayerSprite1.Height / 4))
                        {
                            if (velocity.Y > -GetMaxSpeed())
                            {
                                velocity.Y -= GameParameters.PLAYER_MOVEMENT_ACCELERATION;
                            }
                        }
                        else
                        {
                            velocity.Y = 0.0f;
                            this.position.Y = (PlayerSprite1.Height / 4);
                        }
                    }
                    if (InputHandler.IsKeyDown((Keys)leftKey))
                    {
                        if(this.position.X > (PlayerSprite1.Width / 4))
                        {
                            if (velocity.X > -GetMaxSpeed())
                            {
                                velocity.X -= GameParameters.PLAYER_MOVEMENT_ACCELERATION;
                            }
                        }
                        else
                        {
                            velocity.X = 0.0f;
                            this.position.X = (PlayerSprite1.Width / 4);
                        }
                    }
                    if (InputHandler.IsKeyDown((Keys)downKey))
                    {
                        if(this.position.Y < GameParameters.SCREEN_SIZE.Y - (PlayerSprite1.Height / 4))
                        {
                            if (velocity.Y < GetMaxSpeed())
                            {
                                velocity.Y += GameParameters.PLAYER_MOVEMENT_ACCELERATION;
                            }
                        }
                        else
                        {
                            velocity.Y = 0.0f;
                            this.position.Y = GameParameters.SCREEN_SIZE.Y - (PlayerSprite1.Height / 4);
                        }
                    }
                    if (InputHandler.IsKeyDown((Keys)rightKey))
                    {
                        if (this.position.X < GameParameters.SCREEN_SIZE.X - (PlayerSprite1.Width / 4))
                        {
                            if (velocity.X < GetMaxSpeed())
                            {
                                velocity.X += GameParameters.PLAYER_MOVEMENT_ACCELERATION;
                            }
                        }
                        else
                        {
                            velocity.X = 0.0f;
                            this.position.X = GameParameters.SCREEN_SIZE.X - (PlayerSprite1.Width / 4);
                        }
                    }

                    if (InputHandler.IsKeyUp((Keys)upKey) && velocity.Y < 0.0f)
                    {
                        if (this.position.Y < PlayerSprite1.Height/4)
                        {
                            velocity.Y = 0.0f;
                        }
                        else if (0.0f - velocity.Y < GameParameters.PLAYER_MOVEMENT_DECELERATION)
                        {
                            velocity.Y = 0.0f;
                        }
                        else
                        {
                            velocity.Y += GameParameters.PLAYER_MOVEMENT_DECELERATION;
                        }
                    }
                    if (InputHandler.IsKeyUp((Keys)leftKey) && velocity.X < 0.0f)
                    {
                        if(this.position.X < 0.0f)
                        {
                            velocity.X = 0.0f;
                        }
                        else if (0.0f - velocity.X < GameParameters.PLAYER_MOVEMENT_DECELERATION)
                        {
                            velocity.X = 0.0f;
                        }
                        else
                        {
                            velocity.X += GameParameters.PLAYER_MOVEMENT_DECELERATION;
                        }
                    }
                    if (InputHandler.IsKeyUp((Keys)downKey) && velocity.Y > 0.0f)
                    {
                        if (this.position.Y >= GameParameters.SCREEN_SIZE.Y - PlayerSprite1.Height / 4)
                        {
                            velocity.Y = 0.0f;
                        }
                        else
                        {
                            velocity.Y -= GameParameters.PLAYER_MOVEMENT_DECELERATION;
                        }
                    }
                    if (InputHandler.IsKeyUp((Keys)rightKey) && velocity.X > 0.0f)
                    {
                        if (this.position.X >= GameParameters.SCREEN_SIZE.X)
                        {
                            velocity.X = 0.0f;
                        }
                        else
                        {
                            velocity.X -= GameParameters.PLAYER_MOVEMENT_DECELERATION;
                        }
                    }
                    position += velocity;

                    #endregion Movement

                    #region Debug

                    if (InputHandler.IsKeyDown((Keys)debugKeyReInk))
                    {
                        speedDampener = 1.0f;
                    }
                    break;

                    #endregion Debug

                case PlayerState.Dying:
                        playerState = PlayerState.Dead;
                    break;
                case PlayerState.Dead:
                    // Call Die to removes lives and check if it should respawn
                    Die();

                    break;

                case PlayerState.GameOver:
                    break;
                default:
                    break;
            }
            if (PlayerFactory.Instance().Players.Count > 1)
            {
                foreach(Player p in PlayerFactory.Instance().Players)
                {
                    if(p != this)
                    {
                        if (GetDistance(p.position) < this.sizeInPixels.X * 95/100)
                        {
                            Vector2 dir = new Vector2();
                            dir = this.position - p.position;
                            dir.Normalize();
                            dir = dir * GetMaxSpeed()/10;
                            this.position += dir;
                        }
                    }
                }
            }
        }
        public float GetMaxSpeed()
        {
            return GameParameters.PLAYER_SPEED * speedDampener;
        }
        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            switch (playerState)
            {
                case PlayerState.Spawning:
                    spriteBatch.Draw(Player.PlayerSprite1, position, null, color, 0, new Vector2(Player.PlayerSprite1.Bounds.Center.X, Player.PlayerSprite1.Bounds.Center.Y), scale, SpriteEffects.None, 0);
                    break;

                case PlayerState.Alive:
                    spriteBatch.Draw(Player.PlayerSprite1, position, null, color, 0, new Vector2(Player.PlayerSprite1.Bounds.Center.X, Player.PlayerSprite1.Bounds.Center.Y), scale, SpriteEffects.None, 0);
                    for (int i = 0; i < splodges.Count(); i++)
                    {
                        spriteBatch.Draw(SplodgeSprite, splodges[i].position, null, color, 0, new Vector2(SplodgeSprite.Bounds.Center.X, SplodgeSprite.Bounds.Center.Y), scale, SpriteEffects.None, 0);
                    }
                break;
                case PlayerState.Dying:

                break;
                case PlayerState.Dead:

                break;

                case PlayerState.GameOver:

                break;

                default:
                break;
            }
        }
        public void Splodge()
        {
            GameObject splodge = new GameObject();
            splodge.position = this.position;
            splodges.Add(splodge);
            
        }
        public override void Die()
        {
            // take away 1 life
            Lives--;
            // Check if the player has any lives left to carry on playing
            if (CheckIfLivesLeft())
            {
                // Player can carry on player, set the player to respawming
                playerState =  PlayerState.Spawning;
            }
            else
            {
                // Player has no lives so its game over for him
                Lives = 0;
                NoLivesLeft = true;
                playerState = PlayerState.GameOver;
            }


            //base.Die();
            
        }

        public bool CheckIfLivesLeft()
        {
            return Lives > 0;
        }

    }
}
